/*
 * WSessionFilter.java 
 * 
 *  author: Daniel Rudigier 
 *    date: 24.06.2008
 *    
 *    
 */
package ocumed.web.jsf;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <a
 * href="http://techieexchange.blogspot.com/2008/02/jsf-session-expiry-timeout-solution.html">
 * jsf session timeout validation </a>
 * 
 * @author TechieExchange
 */
public class WSessionFilter implements Filter {
    private static final Log log = LogFactory.getLog(WSessionFilter.class);
    private String timeoutPage = "login.jsf";

    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("session timeout filter loaded");
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain filterChain) throws IOException, ServletException {
        if ((request instanceof HttpServletRequest) 
                && (response instanceof HttpServletResponse)) {

            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            
            /*
            httpServletResponse.addHeader("Cache-Control", "no-cache");
            httpServletResponse.addHeader("Cache-Control", "must-revalidate");
            */
            
            if (isSessionControlRequiredForThisResource(httpServletRequest)) {
                if (isSessionInvalid(httpServletRequest)) {
                    String timeoutUrl = httpServletRequest.getContextPath()
                            + "/" + getTimeoutPage();
                    log.info("session timed out. sending redirect to " + timeoutUrl);
                    httpServletResponse.sendRedirect(timeoutUrl);
                    return;
                } 
            }
        }
        
        filterChain.doFilter(request, response);
    }

    /**
     * filter the login page from redirection
     */
    private boolean isSessionControlRequiredForThisResource(
            HttpServletRequest httpServletRequest) {
        String requestPath = httpServletRequest.getRequestURI();
        boolean controlRequired = requestPath.indexOf(timeoutPage) == -1;
        return controlRequired;
    }

    /**
     * checks the validity of the session
     * 
     * @param httpServletRequest
     * @return
     */
    private boolean isSessionInvalid(HttpServletRequest httpServletRequest) {
        String sid = httpServletRequest.getRequestedSessionId();
        log.info("sid: " + sid);
        log.info(httpServletRequest.isRequestedSessionIdValid());
        
        boolean ret = (sid == null)
                || !httpServletRequest.isRequestedSessionIdValid();
        
        return ret;
    }

    /**
     * override
     * 
     * @see javax.servlet.Filter#destroy()
     */
    public void destroy() {
        log.debug("session timeout filter destroyed");
    }

    /**
     * @return timeoutPage
     */
    public String getTimeoutPage() {
        return timeoutPage;
    }

    /**
     * @param timeoutPage to set
     */
    public void setTimeoutPage(String timeoutPage) {
        this.timeoutPage = timeoutPage;
    }

}
